#ifndef THESAURUS_H
#define THESAURUS_H

#include <QMultiHash>
#include <QString>
#include <QList>

#include "../includes/phrase.h"
#include "../includes/phrasecollection.h"

/**
 * Core functionality. Qt-dependent.
 *
 * A thesaurus/dictionary which maps words to Phrase objects. It
 * is based on a Qt QMultiHash, which is a multi-hash-table, i.e.
 * a hash table with separate chaining. For each hash location,
 * there is a linked list which we receive as a QList of the Phrase objects
 * which hash to that location.
 *
 * The key used to generate the hash is the word as a QString.
 *
 * The hash table is populated with all the words in a PhraseCollection using
 * the populate() method. Words are looked up using the lookup() method.
 *

 * <i>Even more info...</i>
 *
 * Returns a list of (pointers to) Phrase objects synonomous with the given word.
 * Based on a QHashMap. Constructed from a PhraseCollection.
 *
 * word --> [phrase0, phrase1, ... phrase_n]
 *
 * Each word only exists in memory once.
 * Phrase synonyms can be purged to save memory. The relationship between synonyms and
 * phrases is then no longer direct but shifted to the Thesaurus.
 *
 * Uses all lowercase internally.

 * @see Phrase
 * @see PhraseCollection
 * @author Ronen
 */
class Thesaurus {
public:
        // CONSTRUCTORS /////////////////////////////////////////////
        /**
         * Default constructor. Creates an empty Thesaurus.
         * lookup() will never return a match. Invoke populate().
         */
        Thesaurus();
        /**
         * Initialise the thesaurus from a PhraseCollection. All the
         * phrases as well as all their synonyms will be inserted
         * into the hash table.
         * * @param phrases The phrases to insert.
         * @see PhraseCollection
         */
        Thesaurus(PhraseCollection& phrases);
        // METHODS ///////////////////////////////////////////////////
        /**
         * Populate the thesaurus from a PhraseCollection. All the
         * phrases as well as all their synonyms will be inserted
         * into the hash table. The hash table is NOT automatically cleared.
         * @param phrases The phrases to insert.
         * @see PhraseCollection
         */
        void populate(PhraseCollection& phrases);
        /**
         * Look up the phrases corresponding to a given word.
         * @param QString word The word to look up.
         * @return QList of Phrase objects; an empty list if there
         * was no match.
         */
	QList<Phrase*> lookup(const QString& word);
        // HELPER METHODS ////////////////////////////////////////////
private:
        void addWithSubstrings(const QString& word, Phrase* phrase);
        // PRIVATE MEMBERS ///////////////////////////////////////////
private:
	// the data contained in the thesaurus
	// string maps to a list of phrase pointers.
	QMultiHash<QString, Phrase*> stringToPhrasesMap;
};

#endif // THESAURUS_H
